/**  
 * Copyrights@2006, Tianyuan DIC Information Co.,Ltd.
 * 文件名:    TMallPayHandle.java  
 * 描述:   
 * 作者:     kaiyang
 * 版本:    1.0  
 * 创建时间:   2015年5月4日 上午11:57:29  
 *  
 * 修改历史:  
 * 日期                          作者           版本         描述  
 * ------------------------------------------------------------------  
 * 2015年5月4日      kaiyang      1.0        1.0 Version  
 */ 
package com.hp.bon.sgw.wh.channel.handler;

import com.hp.bon.sgw.Constants;
import com.hp.bon.sgw.Constants.MessageType;
import com.hp.bon.sgw.bean.XmlMessage;
import com.hp.bon.sgw.core.BuzProcessorManager;
import com.hp.bon.sgw.core.CallParam;
import com.hp.bon.sgw.core.channel.SoapChannel;
import com.hp.bon.sgw.core.channel.handler.IAsynCallHandler;
import com.hp.bon.sgw.domain.MessageDetail;
import com.hp.bon.sgw.threads.MessageDetailCacheManager;
import com.hp.bon.sgw.threads.TaskManager;
import com.hp.bon.sgw.wh.bean.tmall.TmallFluxBean;
import com.hp.bon.sgw.wh.channel.TMallChannel;
import com.hp.bon.sgw.wh.service.TMallResponseService;
import com.hp.bon.sgw.wh.service.TmallLogDao;
import com.hp.ocs.diameter.message.*;
import org.apache.axis.client.Call;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.io.PrintStream;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**  
 * @ClassName: TMallPayHandle   
 * @Description: TODO  
 * @author: kaiyang  
 * @date:2015年5月4日 上午11:57:29     
 */
public class TmallFlowHandler implements IAsynCallHandler{

	private static final Logger _log = LoggerFactory.getLogger(TaobaoFeeHandle.class);
	private PrintStream printStream;
	private TmallFluxBean tmallFluxBean;
	private TMallResponseService tmallResponseService;
	private ThreadPoolTaskExecutor asynExecutor;
	private String pubKeyValue;
//	private TmallLogDao tmallLogDao;
	private Call call;
	private Call call1;
	private XmlMessage ack;
	
	public XmlMessage getAck() {
		return ack;
	}

	public void setAck(XmlMessage ack) {
		this.ack = ack;
	}

	public TmallFlowHandler(PrintStream printStream,TmallFluxBean tmallFluxBean,TMallResponseService tmallResponseService,
			ThreadPoolTaskExecutor asynExecutor,String pubKeyValue,TmallLogDao tmallLogDao,Call call,Call call1)
	{
		this.printStream = printStream;
        this.tmallFluxBean = tmallFluxBean;
        this.tmallResponseService = tmallResponseService;
        this.asynExecutor = asynExecutor;
        this.pubKeyValue = pubKeyValue;
//        this.tmallLogDao=tmallLogDao;
        this.call = call;
        this.call1 = call1;
	}
	
	@Override
	public int getProtocolType() {
		
		return 0;
	}
  
	@Override
	public void onCallResult(CallParam callParam) {
		XmlMessage ack = null;
		Object response = null;
		String respXML =null;
		if (callParam.getResponse() != null) {
			_log.info("111111111111111111");
			response = callParam.getResponse();
		} else if (callParam.getRecvResponse() != null) {
			_log.info("22222222222222222");
			response = callParam.getRecvResponse();
		}
//		_log.info("ccc"+callParam.getRequest().toString());
//		_log.info("bbb"+callParam.getRequest().getClass().getName());
//		_log.info("aaa"+callParam.getResponse().getClass().getName());
		if (response == null) {
			_log.info("33333333333333333");
			ack = SoapChannel.createERRAnwser(
					callParam.getSessionId(),
					callParam.getRetCode() == 3002 ? 11202 : callParam
							.getRetCode(), callParam.getResultMsg());
		} else {
			if (response instanceof Message) {// CCA -> XML
				_log.info("444444444444444444");
//				ack = BuzProcessorManager.getInstance().convertMessageToAck(
//						callParam);
				setAck(BuzProcessorManager.getInstance().convertMessageToAck(
						callParam));
			
				try {
					_log.info("TmallFlowHandler++"+callParam.getServiceResultCode());
					respXML = convertResponseString((Message)response,callParam.getServiceResultCode());
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			} else if (response instanceof XmlMessage) {
				_log.info("5555555555555555555");
				setAck((XmlMessage) response);
//				ack = (XmlMessage) response;
				respXML = makeResponsMsg();
				_log.info("5555555555555555555"+(XmlMessage)response);
			} else {
				_log.warn("unknown response type:"
						+ callParam.getResponse().getClass().getName());
			}
		}
		try {
			
			_log.info("TmallFlowHandler++after");
			_log.info("TmallFlowHandler++after"+respXML);
			byte[] resp = respXML.getBytes("GBK");
			ack.setLength(resp.length);
			ack.setMsgTime(System.currentTimeMillis());
			printStream.write(resp);
			printStream.close();

			callParam.setResponse(ack);
			_log.info("getRetCode++getRetCode"+callParam.getRetCode());
			if (callParam.getRetCode() == Constants.ResultCode.SUCCESS) {// 成功的消息，请求应答入库

				MessageDetail detail = new MessageDetail();
				detail.setBusinessCallId(callParam.getBussinessCallId());
				detail.setSessionId(callParam.getSessionId());
				detail.setServiceContextId(callParam.getServiceContextId());
				detail.setMessageType(MessageType.WSA);
				detail.setDetails(ack.getDATA());
				detail.setMsgTime(new Date(ack.getMsgTime()));
				detail.setOpType("send");
				detail.setHostId(callParam.getUserName());
				MessageDetailCacheManager.getInstance().add(detail);
			}
			_log.info("http response(taobao----) " + respXML);
			TaskManager.taskProcess(callParam);
			_log.info("http response(taobao) " + respXML);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	/**
	 * 生成外网相应消息 
	 * @param xmlMessage SAOP消息
	 * @return
	 */
	protected String makeResponsMsg() {
		String response="";
		Map<String,String> data = new HashMap<String, String>();
		data.put("tbOrderNo",tmallFluxBean.getTbOrderNo());		
		data.put("bizType",tmallFluxBean.getBizType());	
		StringBuilder respXML = new StringBuilder();
		//SOAP消息有错误，生成网厅错误应答
		if (Integer.valueOf(ack.getRC()).intValue() != 0) {
			if (_log.isInfoEnabled()) 
			{
				_log.info(" xmlMessage.getRC() SOAP消息有错误，生成网厅错误应答 ");
			}
			respXML.append(makeErrFormCCA());
		} else {
			String orinData = ack.getDATA();
			if (orinData != null) {
				Document doc = null;
				String result = "0";
				//云平台黑卡查询接口URL-暂时未定
//				String url = blackCardConfigService.getValue("blackcardquery.url", "");
//				PostMethod method = new PostMethod(url);
				
				try {
					if (_log.isInfoEnabled()) 
					{
						_log.info(" 获取CCA转换后的xml格式的响应数据，orinData :"+orinData );
					}
////					doc = DocumentHelper.parseText(orinData);
////					Element root = doc.getRootElement();
////					result = XmlUtils.getNodevalue(root,"//Service_Information/Result");
//				String homeAreaCode=	XmlUtils.getNodevalue(root,"//Service_Information/Data_Information/HomeAreaCode");
//				String provinceCode=	XmlUtils.getNodevalue(root,"//Service_Information/Data_Information/Province_code");
					Map<String, Object> map = xmlStrToMap(orinData);
					String homeAreaCode = (String) map.get("HomeAreaCode");
					String provinceCode=  (String)map.get("Province_code");
					_log.info("homeAreaCode"+homeAreaCode);
					_log.info("provinceCode"+provinceCode);
			    
//						TmallFluxLog tmallFluxLog =new TmallFluxLog();
//						_log.info("tmallFluxLog");
//							tmallFluxLog.setTbOrderNo(tmallFluxBean.getTbOrderNo());
//							tmallFluxLog.setAccountVal(tmallFluxBean.getAccountVal());
//							tmallFluxLog.setTimeStart(tmallFluxBean.getTimeStart());
//							tmallFluxLog.setSpuId(tmallFluxBean.getSpuId());
//							tmallFluxLog.setTotalPrice(Integer.valueOf(tmallFluxBean.getTotalPrice()));
//							tmallFluxLog.setTbPrice(Integer.valueOf(tmallFluxBean.getTbPrice()));
//							tmallFluxLog.setLatnId(Integer.valueOf(homeAreaCode));
//							tmallFluxLog.setFlag(2);
//							tmallLogDao.insertTmallFluxLog(tmallFluxLog);
							_log.info("insertTmallFluxLog");
							TmallFlowTask task = new TmallFlowTask(tmallFluxBean,null,call,call1,Integer.parseInt(homeAreaCode),pubKeyValue);
							asynExecutor.execute(task);
							
							response = tmallResponseService.getResponse1(data);
//					if(!billingMode.isEmpty()&&!billingMode.equals("")){
//						blackCardMsgIn.setBillingMode(billingMode);	
//					}else{
//						//改动后： 0：后付费C网1：预付费C网；2：固话改点1,在调用云平台的接口之前，给BillingMod赋值规则修改；
//						if(accNbr.startsWith("1")&&accNbr.length()==11){
//							blackCardMsgIn.setBillingMode(XmlUtils.getNodevalue(root,"//Service_Information/Data_Information/PaymentFlag"));
//						}else{
//							blackCardMsgIn.setBillingMode("2");	
//						}
//					}
					
					
					//本地网区号 网厅AccNbr:027,CCA HomeAreaCode:1001(发云平台时需要HomeAreaCode)
//					blackCardMsgIn.setAreaCode(XmlUtils.getNodevalue(root,"//Service_Information/Data_Information/HomeAreaCode"));
//					
//					if (logger.isInfoEnabled()) 
//					{
//						logger.info("result:"+result);
//						logger.info("HomeAreaCode:"+XmlUtils.getNodevalue(root,"//Service_Information/Data_Information/HomeAreaCode"));
//						logger.info("PaymentFlag:"+XmlUtils.getNodevalue(root,"//Service_Information/Data_Information/PaymentFlag"));
//						logger.info("serv_id:"+XmlUtils.getNodevalue(root,"//Service_Information/Data_Information/serv_id"));
//					}
					
					//用户查询接口CCR-CCA -> xml
					//SOAP消息返回结果非0，生成网厅错误应答
//					if (!result.equals("0")) {
//						String errorMsg = "";
//						if(!StringUtils.isEmpty(XmlUtils.getNodevalue(root,"//Service_Information/Para_Field_Result"))){
//							errorMsg = XmlUtils.getNodevalue(root,"//Service_Information/Para_Field_Result");
//						}
//						if (logger.isInfoEnabled()) 
//						{
//							logger.info(" CCR-CCA -> xml " );
//						}
//						respXML.append(makeErrFormCCA(result,errorMsg));
//					}
//					else{
//						
//						//用户查询接口CCR-CCA -> xml
//						//SOAP消息返回结果0，生成云平台查询SOAP请求消息
//						String sendMsg = makeBlackCardMessage();
//						//云平台响应消息
//						String responseMsg = null;
//						logger.info(" PostMethod url:"+url);
//						logger.info(" sendMsg :"+sendMsg );
//
//						//通过httpclient以POST方式向云端发送黑卡查询请求消息。
//						RequestEntity requestEntity = new StringRequestEntity(sendMsg, "text/xml", "UTF-8");
//						method.setRequestEntity(requestEntity);
//						
//						int statusCode = httpClient.executeMethod(method);
//						if (statusCode != HttpStatus.SC_OK) {
//							//httpClient 发送http消息,转态非200，生成网厅错误应答
////							if (logger.isInfoEnabled()) {
//								StringBuilder sbInfo = new StringBuilder();
//								sbInfo.append("sessionid:").append(blackCardMsgIn.getMid()).append(",");
//								sbInfo.append("statusCode:").append(statusCode).append(",");
//								sbInfo.append("sendRequest failed:").append(method.getStatusLine());
//								logger.info(sbInfo.toString());
//								sbInfo.delete( 0, sbInfo.length());
////							}
//							respXML.append(makeErrFormCloud(String.valueOf(statusCode),method.getResponseBodyAsString()));
//						}
//						else {
//							responseMsg = IOUtils.toString(method.getResponseBodyAsStream());
////							if (logger.isInfoEnabled()) {
//								logger.info(" response message from cloud platform:"+responseMsg);
////							}
//							
//							//将云平台的相应结果，格式化为网厅所需的xml响应消息
//							if (responseMsg != null) {
//								doc = DocumentHelper.parseText(responseMsg);
//								root = doc.getRootElement();
//								org.dom4j.Node returnNode =root.selectSingleNode("//return");
//								doc = DocumentHelper.parseText(returnNode.getStringValue());
//								root = doc.getRootElement();
//								
//								String success = XmlUtils.getNodeAttrVal(root,"//HqCheck","success");
//								if (!"true".equals(success)) {
//									//格式化为异常消息
//									String errorCode = XmlUtils.getNodeVal(root,"//HqCheck/errorCode");
//									String errorMsg = XmlUtils.getNodeVal(root,"//HqCheck/errorMsg");
//									respXML.append(makeErrFormCloud(errorCode,errorMsg));
//								}else {
//									//格式化为正常消息
//									respXML.append(makeSuccMsg(root));
//								}
//							}
//						}
//					}
				} catch (DocumentException e) {
					e.printStackTrace();
				}
				catch (Exception e) {
					e.printStackTrace();
				}
				finally {
//					if (method != null) {
//						method.releaseConnection();
//					}
				}
			}
		}
		return response;
//		return respXML.toString();
	}
	public static Map<String, Object> xmlStrToMap(String xmlStr)
			throws Exception {
		_log.info(" CCR-CCA -> xml=== " +xmlStr);
		Map<String, Object> map = new HashMap<String, Object>();
		// 将xml格式的字符串转换成Document对象
		Document doc = DocumentHelper.parseText(xmlStr);
		// 获取根节点
		Element root = doc.getRootElement();
		// 获取根节点下的所有元素
		List children = root.elements();
		// 循环所有子元素
		if (children != null && children.size() > 0) {
			for (int i = 0; i < children.size(); i++) {
				Element child = (Element) children.get(i);
				map.put(child.getName(), child.getTextTrim());
				if (child.getName().equals("returnList")) {
					for (int j = 0; j < child.elements().size(); j++) {
						Element child1 = (Element) child.elements().get(j);
						map.put(child1.getName(), child1.getTextTrim());
						
						if (child1.getName().equals("returnInfo")) {
							for (int k = 0; k < child1.elements().size(); k++) {
								Element child2 = (Element) child1.elements().get(k);
								map.put(child2.getName(), child2.getTextTrim());
							}
						}
						
						
					}
				}
				_log.info(" CCR-CCA -> xml=== " +map);
			}
		}
		return map;
	}
	public static Map<String, Object> xmlStrToMaps(String Str) throws Exception {
		Map<String, Object> map = new HashMap<String, Object>();
		_log.info(" CCR-CCA -> xml " +Str);
		// destinationId=02718971209827@ADSL,minExpDate=201606,requestId=13343421724,requestTime=2016060630,Area_Code=027
		//transactionId=1012300000000201608011722470908,busiTranId=1012300000000201608011722470908,appId=60000052,channelId=113,signCode=SVP320052,capInstId=10123,rtnDataFormatType=XML,contentId=1,regionId=1001,staffCode=hb43235,accNbr=18986137973,pricePlanId=220245,actionType=A
		String[] tmpValues = Str.split(",");

		for (int index = 0; index < tmpValues.length; index++) {
			String tv = tmpValues[index];
			tv = tv.trim();
			if (tv.isEmpty()) {
				continue;
			}

			String[] zu = tv.split("=");
			map.put(zu[0], zu[1]);
		}
		return map;
	}

	private String makeErrFormCCA() {
		StringBuilder sb = new StringBuilder();
		sb.append("<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\">");
		sb.append("<SOAP-ENV:Header/>");
		sb.append("<SOAP-ENV:Body>");
		sb.append("<ns3:SgwQueryAck xmlns:ns3=\"http://www.chinatelecom.cn/SGW/SOAP\">");
		sb.append("<MID>");
//		sb.append(blackCardMsgIn.getMid());
		sb.append("</MID>");
		sb.append("<REPTAG>0</REPTAG>");		
//		sb.append("<RTT>").append(xmlMessage.getRTT()).append("</RTT>");
//		sb.append("<SIG>null</SIG>");
//		sb.append("<RC>").append(xmlMessage.getRC()).append("</RC>");
//		sb.append("<DS>").append(xmlMessage.getDS()).append("</DS>");
		sb.append("<DATA><![CDATA[");
		sb.append("]]>");
	    sb.append("</DATA>");
	    sb.append("</ns3:SgwQueryAck>");		
	    sb.append("</SOAP-ENV:Body>");	
	    sb.append("</SOAP-ENV:Envelope>");	
	    return sb.toString();
	}
	private String convertResponseString(Message answer, int serviceResultCode) throws Exception
	{
//		_log.info("answer= {}",answer.getDictionary().parseToString());
		String response = "";	    	
		Map<String,String> data = new HashMap<String, String>();
		data.put("tbOrderNo",tmallFluxBean.getTbOrderNo());		
		data.put("bizType",tmallFluxBean.getBizType());	
		String Provincecode = "";
		Integer HomeAreaCode = 0;
		_log.info("answer=hhhhhhhh");
		if (serviceResultCode == 0||serviceResultCode == -1)   //鉴权成功
		{
			try{
				_log.info("answer=hhhhhhhh");
			    //service_infomation
			    AVP avp = answer.find(Constants.DIAMETER_AVP_SERVICE_INFOMATION,Constants.DIAMETER_VENDOR_3GPP);
			    AVP_Grouped avpServiceInfomation = new AVP_Grouped(avp);
			    
			    //HomeAreaCode
			    AVP Home_AreaCode = avpServiceInfomation.find(80615,Constants.DIAMETER_VENDOR_CT);
			    if (Home_AreaCode != null)
			    	HomeAreaCode = new AVP_Unsigned32(Home_AreaCode).queryValue();
			    _log.info("HomeAreaCode= {}",HomeAreaCode);
			    //Bill_Serial_Nbr
			    AVP Province_code = avpServiceInfomation.find(81105,Constants.DIAMETER_VENDOR_CT);
			    if (Province_code != null)
			    	Provincecode = new AVP_UTF8String(Province_code).queryValue();
			    _log.info("Provincecode= {}",Provincecode);
			    
			    
			    
			    data.put("coopOrderNo","");
				data.put("coopOrderStatus","UNDERWAY");
				data.put("errCode","");
				data.put("errDesc","");
				
				
//			    TmallFluxLog tmallFluxLog =new TmallFluxLog();
//				tmallFluxLog.setTbOrderNo(tmallFluxBean.getTbOrderNo());
//				tmallFluxLog.setAccountVal(tmallFluxBean.getAccountVal());
//				tmallFluxLog.setTimeStart(tmallFluxBean.getTimeStart());
//				tmallFluxLog.setSpuId(tmallFluxBean.getSpuId());
//				tmallFluxLog.setTotalPrice(Integer.valueOf(tmallFluxBean.getTotalPrice()));
//				tmallFluxLog.setTbPrice(Integer.valueOf(tmallFluxBean.getTbPrice()));
//				tmallFluxLog.setLatnId(Integer.valueOf(HomeAreaCode));
//				tmallFluxLog.setFlag(2);
//				tmallLogDao.insertTmallFluxLog(tmallFluxLog);
				
			}catch(Exception e){
				data.put("coopOrderNo","");
				data.put("coopOrderStatus",TMallChannel.STATUS_FAIL);
				data.put("errCode","0401");
				data.put("errDesc","");
				e.printStackTrace();
				_log.info("异常= {}",e.getMessage());
			}
		}else if (serviceResultCode == 501||serviceResultCode == 502||serviceResultCode == 503||
				serviceResultCode == 504||serviceResultCode == 507||serviceResultCode == 508||serviceResultCode == 531) //充值号码不存在
		{
			data.put("coopOrderNo","");
			data.put("coopOrderStatus",TMallChannel.STATUS_FAIL);
			data.put("errCode","0201");
			data.put("errDesc","");			
		}
		else   //鉴权失败
		{
			data.put("coopOrderNo","");
			data.put("coopOrderStatus",TMallChannel.REQUEST_FAIL);
			data.put("errCode","");
			data.put("errDesc","");
		}
		
		TmallFlowTask task = new TmallFlowTask(tmallFluxBean,null,call,call1,HomeAreaCode,pubKeyValue);
		asynExecutor.execute(task);
		
		response = tmallResponseService.getResponse1(data);
		return response;
	}
	
}
